/*
 * @Author: 精金电子 maicent@qq.com
 * @Date: 2025-03-06 10:28:41
 * @LastEditors: 精金电子 maicent@qq.com
 * @LastEditTime: 2025-03-10 15:36:57
 * @FilePath: \gis-web\src\utils\request.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import axios from 'axios'
import { Message, MessageBox } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'

// 创建axios实例
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 5000 // request timeout
})

console.log('API基础URL:', process.env.VUE_APP_BASE_API)

// 请求拦截器
service.interceptors.request.use(
  config => {
    try {
      // 在请求发送前处理
      if (store.getters.token) {
        // 让每个请求携带token
        // 对于RESTful API，通常使用Bearer认证方案
        const token = getToken()
        if (token) {
          config.headers['Authorization'] = `Bearer ${token}`
        } else {
          console.warn('Token存在但为空')
        }
      } else {
        console.log('请求未添加认证头（无Token）')
      }

      return config
    } catch (error) {
      console.error('请求拦截器错误:', error)
      return Promise.reject(error)
    }
  },
  error => {
    // 请求错误处理
    console.error('请求发送失败:', error)
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  /**
   * 如果你想获取http信息，如headers或status
   * 请返回 response => response
   */

  /**
   * 根据HTTP状态码和响应数据判断请求状态
   * RESTful API通常使用标准HTTP状态码表示请求结果
   */
  response => {
    try {
      const res = response.data
      const status = response.status

      // 2xx 状态码表示成功
      if (status >= 200 && status < 300) {
        return res
      } else {
        // 非2xx状态码处理
        const errorMsg = res.message || '请求错误'
        console.error('响应状态码错误:', {
          status,
          message: errorMsg
        })

        Message({
          message: errorMsg,
          type: 'error',
          duration: 5 * 1000
        })

        return Promise.reject(new Error(errorMsg))
      }
    } catch (error) {
      console.error('响应拦截器处理错误:', error)
      return Promise.reject(error)
    }
  },
  error => {
    try {
      console.error('请求响应错误:', error)

      // 处理不同的HTTP错误状态码
      const { response } = error
      let message = '网络错误，请稍后重试'

      if (response) {
        const { status, data } = response
        console.log('错误响应详情:', {
          status,
          data
        })

        // 根据不同状态码给出不同提示
        switch (status) {
          case 400:
            message = data?.detail || '请求参数错误'
            break
          case 401:
            message = data?.detail || '未授权，请重新登录'

            // 处理401未授权错误，通常需要重新登录
            MessageBox.confirm('您的登录已过期，请重新登录', '登录提示', {
              confirmButtonText: '重新登录',
              cancelButtonText: '取消',
              type: 'warning'
            }).then(() => {
              store.dispatch('user/resetToken').then(() => {
                location.reload()
              })
            }).catch(err => {
              console.log('用户取消了重新登录:', err)
            })
            break
          case 403:
            message = data?.detail || '拒绝访问'
            break
          case 404:
            message = data?.detail || '请求的资源不存在'
            break
          case 500:
            message = data?.detail || '服务器内部错误'
            break
          default:
            message = data?.detail || `请求错误(${status})`
        }
      } else {
        // 没有response对象，可能是网络问题或请求被取消
        if (error.message.includes('timeout')) {
          message = '请求超时，请检查网络'
        } else if (error.message.includes('Network Error')) {
          message = '网络错误，请检查网络连接'
        } else if (axios.isCancel(error)) {
          message = '请求已取消'
          // 请求取消不需要显示错误提示
          return Promise.reject(error)
        }
      }

      // 显示错误消息
      Message({
        message: message,
        type: 'error',
        duration: 5 * 1000
      })

      return Promise.reject(error)
    } catch (err) {
      console.error('响应错误处理器出错:', err)
      Message({
        message: '系统错误，请联系管理员',
        type: 'error',
        duration: 5 * 1000
      })
      return Promise.reject(error)
    }
  }
)

// RESTful API 辅助方法
const http = {
  get(url, params, config = {}) {
    return service.get(url, { params, ...config })
  },
  post(url, data, config = {}) {
    return service.post(url, data, config)
  },
  put(url, data, config = {}) {
    return service.put(url, data, config)
  },
  delete(url, params, config = {}) {
    return service.delete(url, { params, ...config })
  },
  // 原始service实例，用于自定义请求
  service
}

export default http
